home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Amiga Format CD 23
/
Amiga Format AFCD23 (Feb 1998, Issue 107).iso
/
-in_the_mag-
/
emulation
/
computers
/
bkemul
/
source
/
bkemul.s
next >
Wrap
Text File
|
1997-12-12
|
57KB
|
3,296 lines
; © 1997 Russian Digital Computing
; e-mail: r_d_c@usa.net
; bchg.b #1,$bfe001 ; versatile universal debugging tool =)
include /system
include intuition/intuition.i
include intuition/intuition_lib.i
include exec/exec_lib.i
include graphics/graphics_lib.i
include exec/memory.i
include libraries/dos_lib.i
include libraries/dos.i
include dos/dosextens.i
include dos/dostags.i
section emu,code
p0 equr a0
p1 equr a1
p2 equr a2
p3 equr a3
p4 equr d0
p5 equr d1
p6 equr d2
p7 equr d3
ALL_BREAKF equ $f000
;
;------------------------------------------------
; Beginning init
;
start move.l $4.w,_SysBase
movem.l d0/a0,-(sp) ;save initial values
clr.l WB_return_message
sub.l a1,a1
CALLEXEC FindTask
move.l d0,a4
move.l d0,control_proc_ptr ;pointer to our process
tst.l pr_CLI(a4) ;CLI structure present?
bne.s 10$ ;yes
lea pr_MsgPort(a4),a0 ;no - we started from WB
CALLEXEC WaitPort
lea pr_MsgPort(a4),a0
CALLEXEC GetMsg ;get WB msg
move.l d0,WB_return_message
10$ movem.l (sp)+,d0/a0
lea intname,a1
moveq #0,d0
CALLEXEC OpenLibrary ;Intuition
move.l d0,_IntuitionBase
beq err_exit
lea grafname,a1
moveq #0,d0
CALLEXEC OpenLibrary ;Graphics
move.l d0,_GfxBase
beq err_exit
lea dosname,a1
moveq #0,d0
CALLEXEC OpenLibrary ;DOS
move.l d0,_DOSBase
beq err_exit
; --------------------------------------
; CREATE PROCESSOR COMMAND ADDRESS TABLE
; --------------------------------------
;
; Table with 65536 addresses of opcode emulating procedures
;
generate_decode_table
lea ct_vm1,a0
lea decode_table,a1
10$ move.l (a0)+,d0
beq.s 30$
move.w (a0)+,d1
subq.l #1,d1
20$ move.l d0,(a1)+
dbf d1,20$
bra.s 10$
30$
; create opcode timing table (sorry, fake yet)
generate_time_table
lea time_table,a1
move.w #$ffff,d0
10$ move.w #1,(a1)+
dbf d0,10$
; screen convert table for reverse order of bits in screen
; for monochrome screen mode and chunky2planar for color mode
generate_conv_table
lea conv_table,a0
move.l #$10000-1,d0
clr.l d1
10$ move.l d1,d2
rol.w #8,d2
moveq.l #7,d5
clr.w d3
clr.w d4
20$ roxr.w #1,d2
roxl.w #1,d3
roxr.w #1,d2
roxl.w #1,d4
dbf d5,20$
rol.w #8,d4
or.w d3,d4
move.w d4,(a0)+
addq.l #1,d1
dbf d0,10$
move.l #$10000-1,d0
clr.l d1
30$ move.l d1,d2
moveq.l #7,d4
40$ roxr.w #1,d2
roxl.w #1,d3
roxr.w #1,d2
roxl.w #1,d3
dbf d4,40$
rol.w #8,d3
move.w d3,(a0)+
addq.l #1,d1
dbf d0,30$
emulation_preparing
; ROM-file reading
move.l #ROM_file_name,d1
move.l #MODE_OLDFILE,d2
CALLDOS Open
move.l d0,ROM_file_handle
beq err_exit
move.l d0,d1
move.l #emul_buffer_begin,d2
move.l #$8000,d3
CALLDOS Read
cmp.l #-1,d0
beq err_exit
; allocate signal
moveq.l #-1,d0
CALLEXEC AllocSignal
tst.b d0
bmi err_exit
move.b d0,control_proc_signal_bit
moveq.l #1,d1
lsl.l d0,d1
move.l d1,control_proc_signal
; emulation process creation
move.l #decode_proc_tags,d1
CALLDOS CreateNewProc
move.l d0,decode_proc_ptr
beq err_exit
; interface and refresh process creation
move.l #refresh_proc_tags,d1
CALLDOS CreateNewProc
move.l d0,refresh_proc_ptr
beq err_exit
main_loop
move.l control_proc_signal,d0
or.l #ALL_BREAKF,d0
CALLEXEC Wait
and.l #ALL_BREAKF,d0
bne closeall
emt36_handler
move.l emt36_block_ptr,a5
move.l a5,a0
move.b #4,1(a0) ;"STOP" code in response byte
move.w 2(a0),d0 ;beginning address
rol.w #8,d0
move.w d0,emt36_adr
ext.l d0
lea emul_buffer_mid,a1
add.l d0,a1 ;physical address in memory
move.l a1,emt36_ptr
move.w 4(a0),d0
rol.w #8,d0
move.w d0,emt36_len ;length of file
add.l #22,a0 ;end of file name
move.w #15,d1 ;name - 16 characters max
20$ move.b -(a0),d0 ;find real end of file name
cmp.b #32,d0
dbhi d1,20$ ;if character code more than space
tst.w d1 ;d1=name length minus one
bmi emt36_end ;empty name
lea 6(a5),a0 ;begin of name
lea name_buffer,a1
lea koi8_to_1251_table,a2
clr.l d2
30$ move.b (a0)+,d0 ;copy name to buffer for dos call
bpl.s 40$
cmp.b #@240,d0
bls.s 50$
ext.w d0
move.b (a2,d0.w),d0
bra.s 60$
40$ cmp.b #32,d0
bhi.s 60$
blo.s 50$
addq.l #1,d2
bra.s 80$
50$ moveq.b #"_",d0
60$ cmp.b #".",d0
bne.s 70$
sub.l d2,a1
70$ clr.l d2
80$ move.b d0,(a1)+ ;null terminated string
dbf d1,30$
clr.b (a1)+
cmp.b #2,(a5)
beq emt36_write ;command #2 - write
cmp.b #3,(a5)
bne emt36_end
emt36_read
move.l #MODE_OLDFILE,d2
move.l #name_full,d1
CALLDOS Open
move.l d0,emt36_handle
beq emt36_end ;error during file open....
move.l d0,d1
move.l #fib_buffer,d2
CALLDOS ExamineFH ;reading file info block
tst.l d0
beq 100$
lea fib_buffer+fib_Comment,a0 ;comment
clr.b ROM_load_enable ;same flag
clr.l d0 ;address counter
20$ clr.l d1
30$ move.b (a0)+,d0 ;extract address from comment
beq.s 40$
cmp.b #"M",d0
bne.s 33$
clr.b bk_color_mode ;set monochrome mode
33$ cmp.b #"C",d0
bne.s 34$
move.b #-1,bk_color_mode ;set color mode
34$ cmp.b #"R",d0
bne.s 35$
not.b ROM_load_enable ;enable loading in ROM
35$ cmp.b #"S",d0
bne.s 36$
bset.b #7,int_flags ;enable delay
36$ cmp.b #"F",d0
bne.s 37$
bclr.b #7,int_flags ;disable delay
37$ cmp.b #"7",d0
bhi.s 20$
sub.b #"0",d0
bmi.s 20$
asl.w #3,d1 ;next digit
add.w d0,d1
bra.s 30$
40$ tst.w d1
bne.s 50$ ;address present and not zero
lea fib_buffer+fib_DateStamp+ds_Minute,a0 ;time
move.l (a0)+,d1 ;minutes from a.m.
divul.l #60,d2:d1 ;d2 - minutes, d1 - hours
lsl.w #6,d1 ;shift hours
add.w d2,d1 ;add minutes
lsl.w #5,d1 ;shift
move.l (a0)+,d2 ;number of ticks from last minute
divu.l #100,d2 ;number of seconds/2
add.w d2,d1 ;get result - time in MS-DOS format
;it is used on FAT disks in BK OSes.
bne.s 50$
move.w #@40000,d1 ;in zero case
50$ ext.l d1 ;sign extension
move.w d1,d0
rol.w #8,d0
move.w d0,d4
move.l emt36_block_ptr,a5
move.l emt36_ptr,d2 ;address for loading
move.w 2(a5),d5 ;address = zero?
bne.s 60$ ;no
add.l d1,d2 ;yes - add real address to physical
bra.s 70$
60$ move.w d5,d0 ;address not zero - replace default with it
70$ tst.b d0
bpl.s 75$
tst.b ROM_load_enable
beq.s 100$
75$ move.w d0,emul_buffer_mid+@264 ;real load address
move.w d4,@26(a5) ;default load address
move.l fib_buffer+fib_Size,d3 ;real length
tst.w fib_buffer+fib_Size ;test MSW
beq.s 80$ ;length less than 65535 bytes
clr.l d3
moveq.w #-1,d3 ;if file longer
80$ move.w d3,d0
rol.w #8,d0
move.w d0,@30(a5) ;length no more than 65535
move.w d0,emul_buffer_mid+@266 ;--//--
move.l d2,d7 ;buffer
add.l d3,d7 ;end address of loaded data
sub.l #emul_buffer_end,d7 ;load over ROM?
bmi.s 90$
sub.l d7,d3 ;yes - decrease of reading length
90$ move.l emt36_handle,d1
CALLDOS Read
tst.l d0
bmi.s 100$ ;load error
move.l emt36_block_ptr,a5
clr.b 1(a5) ;operation finished succesfully
addq.l #6,a5
lea 20(a5),a6
move.l (a5)+,(a6)+ ;copy name to second part
move.l (a5)+,(a6)+ ;of parameter block
move.l (a5)+,(a6)+
move.l (a5)+,(a6)+
100$ move.l emt36_handle,d1
CALLDOS Close
bra emt36_end
emt36_write
move.l #MODE_NEWFILE,d2
move.l #name_full,d1
CALLDOS Open
move.l d0,emt36_handle
beq emt36_end
move.l d0,d1
move.l emt36_ptr,d2
clr.l d3
move.w emt36_len,d3
clr.l -(sp)
move.l d2,d7 ;buffer
add.l d3,d7 ;end address of loaded data
sub.l #emul_buffer_end,d7 ;load over ROM?
bmi.s 10$
move.l d7,(sp) ;overload
sub.l d7,d3 ;yes - decrease of reading length
10$ CALLDOS Write
move.l (sp)+,d3
beq.s 20$
move.l #emul_buffer_begin,d2
move.l emt36_handle,d1
CALLDOS Write
20$ move.l emt36_handle,d1
CALLDOS Close
lea comment_buffer,a0
move.w emt36_adr,d4
30$ move.w d4,d0
beq.s 40$
lsr.w #3,d4
and.w #@7,d0
add.l #48,d0
move.b d0,-(a0)
bra.s 30$
40$ move.l a0,d2
move.l #name_full,d1
CALLDOS SetComment
move.l emt36_block_ptr,a5
clr.b 1(a5)
emt36_end
move.l decode_proc_ptr,a1
move.l decode_emt36_signal,d0
CALLEXEC Signal
bra main_loop
err_exit
move.l #20,return_code
closeall
; move.l #MODE_NEWFILE,d2
; move.l #data_file_name,d1
; CALLDOS Open
; move.l d0,emt36_handle
; move.l d0,d1
; move.l #data_buffer,d2
; move.l #$40000,d3
; CALLDOS Write
; move.l emt36_handle,d1
; CALLDOS Close
fs1 tst.l control_proc_signal
beq.s rt1
move.b control_proc_signal_bit,d0
CALLEXEC FreeSignal
rt1 tst.l refresh_proc_ptr ;refresh process created?
beq.s rt2 ;no
tst.b control_break_flag ;refresh process terminated?
bne.s rt2 ;yes
addq.b #1,refresh_break_flag ;terminate refresh
10$ move.l #ALL_BREAKF,d0 ;wait for Break signal
CALLEXEC Wait ;(maybe received from anybody)
tst.b control_break_flag ;refresh process terminated?
beq.s 10$ ;NO??? Wait again...
rt2 clr.b control_break_flag
tst.l decode_proc_ptr
beq.s cf1
bset.b #6,int_flags
10$ move.l #ALL_BREAKF,d0 ;wait for Break signal
CALLEXEC Wait ;(maybe received from anybody)
tst.b control_break_flag
beq.s 10$
cf1 move.l ROM_file_handle,d1
beq.s cl1
CALLDOS Close
cl1 move.l _DOSBase,a1
tst.l a1
beq.s cl2
CALLEXEC CloseLibrary
cl2 move.l _GfxBase,a1
tst.l a1
beq.s cl3
CALLEXEC CloseLibrary
cl3 move.l _IntuitionBase,a1
tst.l a1
beq.s ca1
CALLEXEC CloseLibrary
ca1 tst.l WB_return_message
beq.s 10$
CALLEXEC Forbid
move.l WB_return_message,a1
CALLEXEC ReplyMsg
10$ move.l return_code,d0
rts
;----------------------------------------
; SCREEN REFRESH AND CONTROL INTERFACE
;----------------------------------------
;
change_screen_mode ;prepare data for open screen
lea delta_buffer,a0
move.w #1023,d0
10$ clr.l (a0)+
clr.l (a0)+
clr.l (a0)+
clr.l (a0)+
dbf d0,10$
move.l sbs_ptr,a0
clr.l d0
move.w sc_LeftEdge(a0),d0 ;new screen opened over old screen
move.w sc_TopEdge(a0),a1 ;then old screen closed
move.l a0,old_sbs_ptr ;
clr.l sbs_ptr ;
move.l wbs_ptr,old_wbs_ptr ;
clr.l wbs_ptr
move.l cbs_ptr,old_cbs_ptr
clr.l cbs_ptr
not.b bk_color_mode_flag
move.b bk_color_mode_flag,bk_color_mode
bne.s 20$
asl.w #1,d0 ;this is for open new screen
move.l d0,mono_x+4 ;at same physical screen place
move.l a1,mono_y+4 ;where was old screen
bra refresh_proc
20$ asr.w #1,d0
move.l d0,color_x+4
move.l a1,color_y+4
refresh_proc
bsr screen_open ;open new screen
beq refresh_end ;not opened - error
bsr get_bitplane_pointers
clr.l (a1) ;remove point in upper left corner
10$ move.b #1,refresh_counter ;number of vblanks to refresh
bsr refresh ;do refresh
bsr old_screen_close ;close old screen if opened
20$ move.b bk_color_mode_flag,d0
cmp.b bk_color_mode,d0 ;was color mode changed?
bne change_screen_mode ;yes
bsr setjoy ;set joystick bits
bsr get_event ;got any event?
beq.s 30$ ;no
btst #9,d0 ;screen close button pressed?
bne refresh_end ;end of process
btst #10,d0 ;scancode?
beq 205$ ;no
cmp.b #$5f,d1 ;HELP?
bne.s 201$ ;no
tst.b d2 ;rcommand pressed?
bpl change_screen_mode ;no
bchg.b #7,int_flags ;delay on/off
201$ lea keytab1,a0
bsr key_compare
beq.s 30$
cmp.b #14,d1 ;RUS?
beq.s 203$ ;yes
cmp.b #15,d1 ;LAT?
bne.s 25$ ;no
clr.b rus_flag
bra.s 25$
203$ move.b d1,rus_flag
bra.s 25$
205$ cmp.b #27,d1 ;ESC?
bne.s 215$
tst.b d2
bmi.s 207$
bset.b #1,int_flags ;STOP
bra.s 30$
207$ bset.b #0,int_flags ;RESET
bra.s 30$
215$ lea keytab2,a0
bsr.s key_compare
25$ bsr send_code
30$ tst.b refresh_break_flag ;Break received?
bne refresh_end ;yes
move.l decode_proc_ptr,a1
move.l decode_delay_signal,d0
CALLEXEC Signal ;start of sleeping emul proc
btst #0,$bfec01
bne.s 40$
bset #6,p177716+1
40$ CALLGRAF WaitTOF ;wait for vblank
subq.b #1,refresh_counter ;decrease refresh wait counter
bne 20$ ;wait for next event
bra 10$ ;counter=zero -> refresh!
key_compare
10$ move.b (a0)+,d7
beq.s 20$
move.b (a0)+,d6
cmp.b d1,d7
bne.s 10$
move.b d6,d1
20$ rts
refresh_end
bsr all_screens_close ;close all opened screens
addq.b #1,control_break_flag ;terminate main process
move.l control_proc_ptr,a1
move.l #ALL_BREAKF,d0
CALLEXEC Signal ;send Break to it
rts
get_event
move.l cbs_ptr,a0 ;window with
move.l wd_UserPort(a0),a0 ;screen close button
CALLEXEC GetMsg
tst.l d0
bne.s 10$ ;event received
move.l wbs_ptr,a0 ;main backdrop window
move.l wd_UserPort(a0),a0
CALLEXEC GetMsg
tst.l d0
beq.s 20$ ;no new events
10$ move.l d0,a1
move.l im_Class(a1),-(sp) ;what event
move.w im_Code(a1),-(sp)
move.w im_Qualifier(a1),-(sp)
CALLEXEC ReplyMsg ;recycle msg
clr.l d1
clr.l d2
move.w (sp)+,d2
move.w (sp)+,d1
move.l (sp)+,d0
20$ rts
send_code
btst #6,p177716+1
beq.s 30$
btst #7,p177660+1
bne.s 30$
bset #7,p177660+1
bclr #6,p177716+1
btst #6,p177660+1
bne.s 20$
tst.b d1
bmi.s 12$
tst.b d2
bpl.s 14$
12$ bset.b #2,int_flags+1
bra.s 20$
14$ bset.b #1,int_flags+1
20$ and.w #@177,d1
btst #6,d1
beq.s 25$
tst.b rus_flag
bne.s 25$
bchg #5,d1
25$ move.w d1,p177662
30$ rts
screen_open
sub.l a0,a0
lea colortag,a1
move.w #256,wwidth
tst.b bk_color_mode_flag
bne.s 10$
lea monotag,a1
move.w #512,wwidth
10$ CALLINT OpenScreenTagList ;open screen
move.l d0,sbs_ptr
beq 20$
move.l d0,sbs_cop
lea c_bk_screen,a0
CALLINT OpenWindow ;open main backdrop window
move.l d0,cbs_ptr
beq 20$
lea w_bk_screen,a0
CALLINT OpenWindow ;open window with screen
move.l d0,wbs_ptr ;close button
20$ rts
all_screens_close ;close all opened screens
move.l wbs_ptr,a0
clr.l wbs_ptr
move.l cbs_ptr,a1
clr.l cbs_ptr
move.l sbs_ptr,a2
clr.l sbs_ptr
bsr.s screens_close
old_screen_close
move.l old_wbs_ptr,a0
clr.l old_wbs_ptr
move.l old_cbs_ptr,a1
clr.l old_cbs_ptr
move.l old_sbs_ptr,a2
clr.l old_sbs_ptr
screens_close
tst.l a0
beq.s 10$
move.l a1,-(sp)
move.l a2,-(sp)
CALLINT CloseWindow
move.l (sp)+,a2
move.l (sp)+,a1
10$ move.l a1,a0
tst.l a0
beq.s 20$
move.l a2,-(sp)
CALLINT CloseWindow
move.l (sp)+,a2
20$ move.l a2,a0
tst.l a0
beq.s 30$
CALLINT CloseScreen
30$ rts
refresh
lea emul_buffer_mid+@40000,a0 ;begin screen address
lea @40000(a0),a4 ;end screen address
lea delta_buffer,a5 ;delta-buffer
bsr get_bitplane_pointers
lea conv_table,a3 ;color conversion table
tst.b bk_color_mode_flag ;color or monochrome
bne.s 20$ ;if monochrome - then get
add.l #$20000,a3 ;second half of table
20$ clr.l d1
clr.l d3
move.w #256,d4
clr.l d5
move.w p177664,d3
move.w d3,d6
and.w #@1000,d6
bne.s 30$
asr.w #2,d4
cmp.w c177664,d6
beq.s 30$
move.w #1535,d5
30$ move.w d6,c177664
sub.w #@330,d3 ;calculate real address
and.w #$ff,d3 ;beginning of screen
asl.w #6,d3
add.l d3,a0
subq.w #1,d4
clr.l d3 ;refresh cycles counter
tst.b bk_color_mode_flag
beq mono_refresh
color_refresh
CSC MACRO
10\1$ cmp.l (a0)+,(a5)+
beq.s 11\1$
move.l (a0),(a5)
bra.s 12\1$
11\1$ cmp.l (a0)+,(a5)+
beq.s 10\2$
move.l -(a0),-(a5)
12\1$ move.l -(a0),-(a5)
bsr color_converter
move.l d6,\3(a1)
move.l d7,\3(a2)
ENDM
10$ CSC 0,1,$00
CSC 1,2,$04
CSC 2,3,$08
CSC 3,4,$0C
CSC 4,5,$10
CSC 5,6,$14
CSC 6,7,$18
CSC 7,8,$1C
108$ add.w #32,a1
add.w #32,a2
cmp.l a0,a4
bne.s 20$
sub.l #$4000,a0
20$ dbf d4,10$
bsr test_delay
tst.w d5
beq.s 80$
add.w #$3000,a5
add.w #$1800,a1
add.w #$1800,a2
30$ tst.l -(a5)
bne.s 50$
tst.l -(a5)
beq.s 40$
clr.l (a5)
bra.s 60$
40$ subq.l #4,a1
subq.l #4,a2
bra.s 70$
50$ clr.l (a5)
clr.l -(a5)
60$ clr.l -(a1)
clr.l -(a2)
70$ dbf d5,30$
80$ rts
mono_refresh
CSM MACRO
10\1$ cmp.l (a0)+,(a5)+
beq.s 11\1$
move.l (a0),(a5)
bra.s 12\1$
11\1$ cmp.l (a0)+,(a5)+
beq.s 10\2$
move.l -(a0),-(a5)
12\1$ move.l -(a0),-(a5)
bsr mono_converter
move.l d2,\3(a1)
move.l d6,\3+4(a1)
ENDM
10$ CSM 0,1,$00
CSM 1,2,$08
CSM 2,3,$10
CSM 3,4,$18
CSM 4,5,$20
CSM 5,6,$28
CSM 6,7,$30
CSM 7,8,$38
108$ add.w #64,a1
cmp.l a0,a4
bne.s 20$
sub.l #$4000,a0
20$ dbf d4,10$
bsr test_delay
tst.w d5
beq.s 80$
add.w #$3000,a5
add.w #$3000,a1
30$ tst.l -(a5)
bne.s 40$
subq.l #4,a1
bra.s 50$
40$ clr.l (a5)
clr.l -(a1)
50$ tst.l -(a5)
bne.s 60$
subq.l #4,a1
bra.s 70$
60$ clr.l (a5)
clr.l -(a1)
70$ dbf d5,30$
80$ rts
test_delay
btst.b #7,int_flags ;delay on?
bne 10$ ;yes
cmp.l #1024,d3 ;half screen or more was refreshed?
blo 10$
addq.b #1,refresh_counter ;more - delay next refresh
10$ rts
get_bitplane_pointers
move.l sbs_ptr,a1
move.l sc_RastPort+rp_BitMap(a1),a1 ;screen bitmap
move.l bm_Planes+4(a1),a2 ;second bitplane
move.l bm_Planes(a1),a1 ;first bitplane
rts
color_converter
addq.l #1,d3
addq.l #8,a5
move.w (a0)+,d1
move.w 0(a3,d1.l*2),d2
move.b d2,d6
move.w d2,d7
rol.w #8,d6
move.w (a0)+,d1
move.w 0(a3,d1.l*2),d2
move.b d2,d6
rol.w #8,d2
move.b d2,d7
swap d6
swap d7
move.w (a0)+,d1
move.w 0(a3,d1.l*2),d2
move.b d2,d6
move.w d2,d7
rol.w #8,d6
move.w (a0)+,d1
move.w 0(a3,d1.l*2),d2
move.b d2,d6
rol.w #8,d2
move.b d2,d7
rts
mono_converter
addq.l #1,d3
addq.l #8,a5
move.w (a0)+,d1
move.w 0(a3,d1.l*2),d2
swap d2
move.w (a0)+,d1
move.w 0(a3,d1.l*2),d2
move.w (a0)+,d1
move.w 0(a3,d1.l*2),d6
swap d6
move.w (a0)+,d1
move.w 0(a3,d1.l*2),d6
rts
;------------------------------
;------------------------------
; PROCESSOR EMULATION ROUTINES
;------------------------------
;------------------------------
; ------------------
; MACRO COMMANDS SET
; ------------------
;
BK_RB MACRO ;reading byte (\1) to \2
cmp.w #@177600,\1 ;check ports address space
blo.s *+6 ;no
bsr rbp_\1\2 ;port reading
move.b (a4,\1.w),\2 ;done
ENDM
BK_RW MACRO ;reading word (\1) to \2
bclr.l #0,\1 ;align to even
cmp.w #@177600,\1 ;check ports address space
blo.s *+6 ;no
bsr rwp_\1\2 ;port reading
move.w (a4,\1.w),\2 ;done
rol.w #8,\2 ;swap bytes
ENDM
BK_SB MACRO ;write byte \1 to (\2)
tst.w \2 ;check ports & ROM address space
bpl.s *+6 ;no
bsr wbp_\1\2 ;write to port or bus error
move.b \1,(a4,\2.w) ;done
ENDM
BK_NSW MACRO ;write word \1 to (\2)
tst.w \2 ;check ports & ROM address space
bpl.s *+6 ;no
bsr wwp_\1\2 ;write to port or bus error
rol.w #8,\1 ;swap bytes
move.w \1,(a4,\2.w) ;done
ENDM
BK_SW MACRO ;BK_NSW plus address align
bclr.l #0,\2
BK_NSW \1,\2
ENDM
BK_RRW MACRO ;BK_RW without \1 trashing
move.w \1,\2
BK_RW \2,\2
ENDM
CALL MACRO ;JSR without stack operations
lea *+6(pc),\2
jmp (\1)
ENDM
RET MACRO ;RTS without stack operations
jmp (\1)
ENDM
RETCMD MACRO
bra dc_next
ENDM
rbp MACRO
rbp_\1\2
movem.l d0-a6,-(sp)
move.l \1,a6
bsr rbp_
move.w d6,rmem
movem.l (sp)+,d0-a6
move.w rmem,\2
addq.l #4,(sp)
rts
ENDM
rwp MACRO
rwp_\1\2
movem.l d0-a6,-(sp)
move.l \1,a6
bsr rwp_
move.w d6,rmem
movem.l (sp)+,d0-a6
move.w rmem,\2
addq.l #6,(sp)
rts
ENDM
wbp MACRO
wbp_\1\2
movem.l d0-a6,-(sp)
move.l \2,a6
move.l \1,d6
bsr wbp_
movem.l (sp)+,d0-a6
addq.l #4,(sp) ;skip write operation
rts
ENDM
wwp MACRO
wwp_\1\2
movem.l d0-a6,-(sp)
move.l \2,a6
move.l \1,d6
bsr wwp_
movem.l (sp)+,d0-a6
addq.l #6,(sp) ;skip ROL.W #8 and write operation
rts
ENDM
dCMD MACRO
dc.l \1
dc.w \2
ENDM
CMD_Rx MACRO
dCMD \1r0,1
dCMD \1r1,1
dCMD \1r2,1
dCMD \1r3,1
dCMD \1r4,1
dCMD \1r5,1
dCMD \1r6,1
dCMD \1r7,1
dCMD \1__,56
ENDM
CMD_Rm MACRO
dCMD \1r0,1
dCMD \1r1,1
dCMD \1r2,1
dCMD \1r3,1
dCMD \1r4,1
dCMD \1r5,1
dCMD \1r6,1
dCMD \1r7,1
ENDM
CMD_Rn MACRO
dCMD \1r0,64
dCMD \1r1,64
dCMD \1r2,64
dCMD \1r3,64
dCMD \1r4,64
dCMD \1r5,64
dCMD \1r6,64
dCMD \1r7,64
ENDM
FCMD_Rn MACRO
_\1r0 \1rn p0
_\1r1 \1rn p1
_\1r2 \1rn p2
_\1r3 \1rn p3
_\1r4 \1rn p4
_\1r5 \1rn p5
_\1r6 \1rn p6
_\1r7 \1rn p7
ENDM
; -----------------
; PORTS EMULATION
; -----------------
rmem dc.w 0
rbp_ move.l sp,a5
move.w a6,d0 ;reading byte from port
btst.l #0,d0 ;check LSbit of address
beq.s rwp_ ;even address
bsr.s rwp_ ;odd address
rol.w #8,d6 ;swap bytes
rts
rwp_ move.l sp,a5
move.w a6,d0
asr.w #1,d0
lea prt_vm1,a0
move.l (a0,d0.w*4),a0
tst.l a0
beq.s halt
jmp (a0)
wbp_ move.l sp,a5
move.w a6,d0
and.w #$ff,d6 ;clear MSbyte
btst.l #0,d0 ;check if address even
beq.s wwp_ ;even
rol.w #8,d6 ;odd - write byte as MS
wwp_ move.l sp,a5
move.w a6,d0
cmp.w #@177600,d0 ;write to ports?
blo.s halt ;write to ROM!
asr.w #1,d0 ;convert byte address to word address
lea pwt_vm1,a0 ;hardware emulating routines table
move.l (a0,d0.w*4),a0 ;select address
tst.l a0
beq.s halt ;no device response - bus error
jmp (a0) ;emulating device
halt move.l a5,sp
addq.l #4,sp
movem.l (sp)+,d0-a6 ;restore registers
move.l decode_init_stack,sp ;restore stack
btst.b #0,int_flags ;check reset flag
bne.l reset
moveq.l #4,d6 ;bus error exception
bsr.l int
RETCMD
reset_hw
clr.b rus_flag
move.w #@100,p177660
rts
wp177660
move.w p177660,d1
bclr.l #6,d1
and.w #@100,d6
or.w d6,d1
move.w d1,p177660
rts
rp177660
move.w p177660,d6
rts
rp177662
move.w p177662,d6
move.w p177660,d1
bclr.l #7,d1
move.w d1,p177660
rts
wp177664
and.w #%1011111111,d6
move.w d6,p177664
rts
rp177664
move.w p177664,d6
rts
wp177716
rts
rp177716
move.w p177716,d6
rts
wp177714
rts
rp177714
move.w p177714,d6
rts
setjoy clr.l d6 ;joystick emulation
move.w $dff00c,d0
btst.l #9,d0
beq.s 10$
bset.l #1,d6 ;left
btst.l #8,d0
bne.s 30$
bra.s 20$
10$ btst.l #8,d0
beq.s 30$
20$ bset.l #2,d6 ;forward
30$ btst.l #1,d0
beq.s 40$
bset.l #0,d6 ;right
btst.l #0,d0
bne.s 60$
bra.s 50$
40$ btst.l #0,d0
beq.s 60$
50$ bset.l #3,d6 ;back
60$ tst.b $bfe001
bmi.s 70$
bset.l #5,d6 ;fire0
70$ btst.b #6,$dff016
bne.s 80$
bset.l #4,d6 ;fire1
80$ move.w d6,p177714
rts
rp177700
rts
rp177702
rts
rp177704
rts
rp177706
rts
rp177710
rts
rp177712
rts
wp177700
rts
wp177702
rts
wp177704
rts
wp177706
rts
wp177710
rts
wp177712
rts
_emt_36
movem.l d0-a6,-(sp)
add.w p1,a4
move.l a4,emt36_block_ptr
move.l control_proc_signal,d0
move.l control_proc_ptr,a1
CALLEXEC Signal
move.l decode_emt36_signal,d0
CALLEXEC Wait
movem.l (sp)+,d0-a6
RETCMD
wbp d4,p0
wbp d4,p1
wbp d4,p2
wbp d4,p3
wbp d4,p4
wbp d4,p5
wbp d4,p6
wbp d4,p7
wbp d6,p0
wbp d6,p1
wbp d6,p2
wbp d6,p3
wbp d6,p4
wbp d6,p5
wbp d6,p6
wbp d6,p7
wbp d4,d6
wbp d6,d7
wbp d5,d4
rbp p0,d4
rbp p1,d4
rbp p2,d4
rbp p3,d4
rbp p4,d4
rbp p5,d4
rbp p6,d4
rbp p7,d4
rbp p0,d6
rbp p1,d6
rbp p2,d6
rbp p3,d6
rbp p4,d6
rbp p5,d6
rbp p6,d6
rbp p7,d6
rbp d4,d4
rbp d7,d6
rbp d6,d5
rbp d4,d5
rwp d4,d4
rwp d6,d6
rwp d6,d3
rwp d4,d3
rwp d7,d7
rwp d7,d6
rwp d4,d6
rwp d1,d1
wwp d3,d4
wwp d4,d7
wwp d4,d6
wwp d6,d7
; ----------------------------
; OPCODES EMULATING ROUTINES
; ----------------------------
;
; Software exceptions
;
_halt__ moveq.l #4,d6
bra.s intc
_rsrv__ moveq.l #@10,d6
bra.s intc
_bpt___ moveq.l #@14,d6
bra.s intc
_iot___ moveq.l #@20,d6
bra.s intc
_emt___ moveq.l #@30,d6
bra.s intc
_trap__ moveq.l #@34,d6
intc bsr.s int
RETCMD
;
;----------------------------
; EXCEPTION HANDLING
; d6 - vector
;
int move.w d2,d4
subq.w #2,d4
bclr.l #0,d4
BK_SB d5,d4
subq.w #2,d4
BK_NSW d3,d4
BK_RW d6,d3
addq.w #2,d6
BK_RB d6,d5
bclr.b #2,int_flags
btst.l #4,d5
beq.s 10$
bset.b #2,int_flags
10$ subq.w #4,d2
rts
_reset_ bsr reset_hw
RETCMD
_wait__
; movem.l d0-a6,-(sp)
; addq.b #1,wait_flag
; move.l decode_emt36_signal,d0
; CALLEXEC Wait
; movem.l (sp)+,d0-a6
RETCMD
;----------------------------
; Return from exception
;
_rti___
move.w d2,d4
BK_RW d4,d3
addq.w #2,d4
BK_RB d4,d5
bclr.b #2,int_flags
btst.l #4,d5
beq.s 10$
bset.b #2,int_flags
10$ addq.w #4,d2
RETCMD
_rtt___
move.w d2,d4
BK_RW d4,d3
addq.w #2,d4
BK_RB d4,d5
bclr.b #2,int_flags
btst.l #4,d5
beq.s 10$
bset.b #2,int_flags
10$ addq.w #4,d2
clr.l d4
bra.l dc_rtt
; Condition flags changing
_se____ and.w #$F,d4
or.w d4,d5
RETCMD
_cl____ and.w #$F,d4
not.w d4
and.w d4,d5
RETCMD
;------------------------------------------------
; conditional and unconditional branches
; fully same as Motorola's
;
_bne___ move.b d5,ccr
bne.s _br____
RETCMD
_beq___ move.b d5,ccr
beq.s _br____
RETCMD
_bvc___ move.b d5,ccr
bvc.s _br____
RETCMD
_bvs___ move.b d5,ccr
bvs.s _br____
RETCMD
_bcc___ move.b d5,ccr
bcc.s _br____
RETCMD
_bcs___ move.b d5,ccr
bcc dc_next
_br____ ext.w d4
asl.w #1,d4
add.w d4,d3
RETCMD
_bge___ move.b d5,ccr
bge.s _br____
RETCMD
_blt___ move.b d5,ccr
blt.s _br____
RETCMD
_bgt___ move.b d5,ccr
bgt.s _br____
RETCMD
_ble___ move.b d5,ccr
ble.s _br____
RETCMD
_bhi___ move.b d5,ccr
bhi.s _br____
RETCMD
_blos__ move.b d5,ccr
bls.s _br____
RETCMD
_bpl___ move.b d5,ccr
bpl.s _br____
RETCMD
_bmi___ move.b d5,ccr
bmi.s _br____
RETCMD
;
;-------------------------------
; JSR Rn,N - Subroutine call
;
jsr_rn MACRO
and.w #%111111,d4
lea ad_jw(pc),a6
move.l (a6,d4.l*4),a6
CALL a6,a5
move.w \1,d4
subq.w #2,d2 ;shift stack
move.w d2,d7
BK_SW d4,d7
move.w d3,\1
move.w d6,d3
RETCMD
ENDM
FCMD_Rn jsr_ ;set of eight routines
;
;-------------------------------
; JMP N - Unconditional jump
;
_jmp___ and.w #%111111,d4
lea ad_jw(pc),a6
move.l (a6,d4.l*4),a6
CALL a6,a5
move.w d6,d3
RETCMD
;
;-----------------------------------
; RTS Rn - Return from subroutine
;
rts_rn MACRO
move.w \1,d3 ;copy register to program counter
BK_RRW d2,d4
move.w d4,\1
addq.w #2,d2 ;stack increment
RETCMD
ENDM
FCMD_Rn rts_
;
;-----------------------------------------
; MARK N - Stack restore
; big thanx to Alexei Saveliev for description
;
_mark__ and.w #%111111,d4 ;lower six bits
asl.w #1,d4 ;x2
add.w d3,d4 ;add program counter
move.w d4,d2 ;PC+2N->SP
move.w d1,d3 ;R5->PC
BK_RRW d2,d1 ;(SP)->R5
addq.w #2,d2 ;(SP)+
RETCMD
;
;-------------------------------
; SOB Rn,N - Cycle
;
sob_rn MACRO
subq.w #1,\1
tst.w \1
beq.l dc_next ;register=zero
and.w #%111111,d4 ;extract offset
asl.w #1,d4 ;x2
sub.w d4,d3 ;decrease program counter by offset x 2
RETCMD
ENDM
FCMD_Rn sob_
;
;---------------------------------
; MOV(B) S,D - Move
;
m_f_rn MACRO
and.w #@77,d4
lea ad_ww(pc),a6
move.l (a6,d4.l*4),a6
move.w \1,d4
move.w ccr,d7
and.w #%00001100,d7
and.w #%11110001,d5
or.w d7,d5
jmp (a6)
ENDM
mbf_rn MACRO
and.w #@77,d4
lea ad_wb(pc),a6
move.l (a6,d4.l*4),a6
move.w \1,d4
ext.w d4
move.w ccr,d7
and.w #%00001100,d7
and.w #%11110001,d5
or.w d7,d5
jmp (a6)
ENDM
m_t_rn MACRO
and.w #@7700,d4
asr.l #6,d4
lea ad_rw(pc),a6
move.l (a6,d4.l*4),a6
CALL a6,a5
tst.w d4
move.w ccr,d7
and.w #%00001100,d7
and.w #%11110001,d5
or.w d7,d5
move.w d4,\1
RETCMD
ENDM
mbt_rn MACRO
and.w #@7700,d4
asr.l #6,d4
lea ad_rb(pc),a6
move.l (a6,d4.l*4),a6
CALL a6,a5
ext.w d4
move.w ccr,d7
and.w #%00001100,d7
and.w #%11110001,d5
or.w d7,d5
move.w d4,\1
RETCMD
ENDM
FCMD_Rn m_f_
FCMD_Rn mbf_
FCMD_Rn m_t_
FCMD_Rn mbt_
_mov___ move.l d4,d6
and.w #%111111000000,d4
asr.l #6,d4
lea ad_rw(pc),a6
move.l (a6,d4.l*4),a6
CALL a6,a5
tst.w d4
move.w ccr,d7
and.w #%00001100,d7
and.w #%11110001,d5
or.w d7,d5
and.w #%111111,d6
lea ad_ww(pc),a6
move.l (a6,d6.l*4),a6
jmp (a6)
_movb__ move.l d4,d6
and.w #%111111000000,d4
asr.l #6,d4
lea ad_rb(pc),a6
move.l (a6,d4.l*4),a6
CALL a6,a5
ext.w d4
move.w ccr,d7
and.w #%00001100,d7
and.w #%11110001,d5
or.w d7,d5
and.w #%111111,d6
lea ad_wb(pc),a6
move.l (a6,d6.l*4),a6
jmp (a6)
;--------------------------------------------
; ADDRESSING MODES ADDRESS ROUTINES TABLES
;--------------------------------------------
;
at_reg MACRO
dc.l ad\2\1\3
ENDM
at_nreg MACRO
at_reg 0,\1,\2
at_reg 1,\1,\2
at_reg 2,\1,\2
at_reg 3,\1,\2
at_reg 4,\1,\2
at_reg 5,\1,\2
at_reg 6,\1,\2
at_reg 7,\1,\2
ENDM
at_nad MACRO
ad_\1 at_nreg 0,\1
at_nreg 1,\1
at_nreg 2,\1
at_nreg 3,\1
at_nreg 4,\1
at_nreg 5,\1
at_nreg 6,\1
at_nreg 7,\1
ENDM
cnop 0,4
at_nad rb
at_nad rw
at_nad wb
at_nad ww
at_nad mb
at_nad mw
at_nad jw
;------------------------------------------------
; MxPS S(D) - Move processor status word
;
_mfps__ move.l d4,d6
move.w d5,d4
move.w ccr,d7
and.w #%00001100,d7
and.w #%11110001,d5
or.w d7,d5
and.w #%111111,d6
lea ad_wb(pc),a6
move.l (a6,d6.l*4),a6
jmp (a6)
_mtps__ and.w #%111111,d4
lea ad_rb(pc),a6
move.l (a6,d4.l*4),a6
CALL a6,a5
and.l #%11101111,d4
and.l #%00010000,d5
or.l d4,d5
RETCMD
;---------------------------------
; CLR(B) D - Clear
;
_clr___ move.l d4,d6
and.w #%11110000,d5
or.w #%00000100,d5
clr.l d4
and.w #%111111,d6
lea ad_ww(pc),a6
move.l (a6,d6.l*4),a6
jmp (a6)
_clrb__ move.l d4,d6
and.w #%11110000,d5
or.w #%00000100,d5
clr.l d4
and.w #%111111,d6
lea ad_wb(pc),a6
move.l (a6,d6.l*4),a6
jmp (a6)
clr_rn MACRO
clr.w d4
move.w d4,\1
bra.s _clr_rx
ENDM
clrbrn MACRO
move.w \1,d4
clr.b d4
move.w d4,\1
bra.s _clr_rx
ENDM
FCMD_Rn clr_
FCMD_Rn clrb
nop
_clr_rx and.w #%11110000,d5
or.w #%00000100,d5
RETCMD
;---------------------------------
; TST(B) S - Test and set flags
;
tst_rn MACRO
tst.w \1
bra.s _tst_rx
ENDM
tstbrn MACRO
move.w \1,d4
tst.b d4
bra.s _tst_rx
ENDM
FCMD_Rn tst_
FCMD_Rn tstb
_tst___ and.w #%111111,d4
lea ad_rw(pc),a6
move.l (a6,d4.l*4),a6
CALL a6,a5
tst.w d4
_tst_rx move.w ccr,d4
and.w #%00001100,d4
and.w #%11110000,d5
or.w d4,d5
RETCMD
_tstb__ and.w #%111111,d4
lea ad_rb(pc),a6
move.l (a6,d4.l*4),a6
CALL a6,a5
tst.b d4
move.w ccr,d4
and.w #%00001100,d4
and.w #%11110000,d5
or.w d4,d5
RETCMD
;-------------------------------------
; COM(B) D - Inversion
;
_com___ and.w #%111111,d4
lea ad_mw(pc),a6
move.l (a6,d4.l*4),a6
lea 1$(pc),a5
jmp (a6)
1$ not.w d6
move.w ccr,d4
and.w #%00001100,d4
addq.w #1,d4
and.w #%11110000,d5
or.w d4,d5
RET a6
_comb__ and.w #%111111,d4
lea ad_mb(pc),a6
move.l (a6,d4.l*4),a6
lea 1$(pc),a5
jmp (a6)
1$ not.b d6
move.w ccr,d4
and.w #%00001100,d4
addq.w #1,d4
and.w #%11110000,d5
or.w d4,d5
RET a6
;-------------------------------------
; INC(B) D - Increment
;
_inc___ and.w #%111111,d4
lea ad_mw(pc),a6
move.l (a6,d4.l*4),a6
lea 1$(pc),a5
jmp (a6)
1$ addq.w #1,d6
move.w ccr,d4
and.w #%00001110,d4
and.w #%11110001,d5
or.w d4,d5
RET a6
_incb__ and.w #%111111,d4
lea ad_mb(pc),a6
move.l (a6,d4.l*4),a6
lea 1$(pc),a5
jmp (a6)
1$ addq.b #1,d6
move.w ccr,d4
and.w #%00001110,d4
and.w #%11110001,d5
or.w d4,d5
RET a6
;-------------------------------------
; DEC(B) D - Decrement
;
_dec___ and.w #%111111,d4
lea ad_mw(pc),a6
move.l (a6,d4.l*4),a6
lea 1$(pc),a5
jmp (a6)
1$ subq.w #1,d6
move.w ccr,d4
and.w #%00001110,d4
and.w #%11110001,d5
or.w d4,d5
RET a6
_decb__ and.w #%111111,d4
lea ad_mb(pc),a6
move.l (a6,d4.l*4),a6
lea 1$(pc),a5
jmp (a6)
1$ subq.b #1,d6
move.w ccr,d4
and.w #%00001110,d4
and.w #%11110001,d5
or.w d4,d5
RET a6
;------------------------------------------
; SWAB D - Swap bytes in word
;
_swab__ and.w #%111111,d4
lea ad_mw(pc),a6
move.l (a6,d4.l*4),a6
lea 1$(pc),a5
jmp (a6)
1$ rol.w #8,d6
tst.b d6
move.w ccr,d4
and.w #%00001100,d4
and.w #%11110000,d5
or.w d4,d5
RET a6
;------------------------------------------
; SXT D - Sign flag extension
;
_sxt___ and.w #%111111,d4
lea ad_mw(pc),a6
move.l (a6,d4.l*4),a6
lea 1$(pc),a5
jmp (a6)
1$ move.w d5,d6
rol.w #4,d6
extb.l d6
swap d6
tst.w d6
move.w ccr,d4
and.w #%00000100,d4
and.w #%11111001,d5
or.w d4,d5
RET a6
;-------------------------------------
; NEG(B) D - Sign change
;
_neg___ and.w #%111111,d4
lea ad_mw(pc),a6
move.l (a6,d4.l*4),a6
lea 1$(pc),a5
jmp (a6)
1$ neg.w d6
move.w ccr,d4
and.w #%00001111,d4
and.w #%11110000,d5
or.w d4,d5
RET a6
_negb__ and.w #%111111,d4
lea ad_mb(pc),a6
move.l (a6,d4.l*4),a6
lea 1$(pc),a5
jmp (a6)
1$ neg.b d6
move.w ccr,d4
and.w #%00001111,d4
and.w #%11110000,d5
or.w d4,d5
RET a6
;-------------------------------------
; ASL(B) D - Arithmetic left shift
;
asl_rn MACRO
move.w \1,d6
asl.w #1,d6
move.w ccr,d4
and.w #%00001111,d4
and.w #%11110000,d5
or.w d4,d5
move.w d6,\1
RETCMD
ENDM
aslbrn MACRO
move.w \1,d6
asl.b #1,d6
move.w ccr,d4
and.w #%00001111,d4
and.w #%11110000,d5
or.w d4,d5
move.w d6,\1
RETCMD
ENDM
FCMD_Rn asl_
FCMD_Rn aslb
_asl___ and.w #%111111,d4
lea ad_mw(pc),a6
move.l (a6,d4.l*4),a6
lea 1$(pc),a5
jmp (a6)
1$ asl.w #1,d6
move.w ccr,d4
and.w #%00001111,d4
and.w #%11110000,d5
or.w d4,d5
RET a6
_aslb__ and.w #%111111,d4
lea ad_mb(pc),a6
move.l (a6,d4.l*4),a6
lea 1$(pc),a5
jmp (a6)
1$ asl.b #1,d6
move.w ccr,d4
and.w #%00001111,d4
and.w #%11110000,d5
or.w d4,d5
RET a6
;-------------------------------------
; ASR(B) D - Arithmetic rigth shift
;
asr_rn MACRO
move.w \1,d6
asr.w #1,d6
move.w ccr,d4
move.w d6,\1
and.w #%00001111,d4
and.w #%11110000,d5
or.w d4,d5
RETCMD
ENDM
asrbrn MACRO
move.w \1,d6
asr.b #1,d6
move.w ccr,d4
move.w d6,\1
and.w #%00001111,d4
and.w #%11110000,d5
or.w d4,d5
RETCMD
ENDM
FCMD_Rn asr_
FCMD_Rn asrb
_asr___ and.w #%111111,d4
lea ad_mw(pc),a6
move.l (a6,d4.l*4),a6
lea 1$(pc),a5
jmp (a6)
1$ asr.w #1,d6
move.w ccr,d4
and.w #%00001111,d4
and.w #%11110000,d5
or.w d4,d5
RET a6
_asrb__ and.w #%111111,d4
lea ad_mb(pc),a6
move.l (a6,d4.l*4),a6
lea 1$(pc),a5
jmp (a6)
1$ asr.b #1,d6
move.w ccr,d4
and.w #%00001111,d4
and.w #%11110000,d5
or.w d4,d5
RET a6
;-------------------------------------
; ROL(B) D - Cycle left shift
;
rol_rn MACRO
move.w \1,d6
move.l d5,d4
roxr.l #1,d4
roxl.w #1,d6
bmi.s 2$
bcc.s 3$
or #2,ccr
bra.s 3$
2$ bcs.s 3$
or #2,ccr
3$ move.w ccr,d4
move.w d6,\1
and.w #%00001111,d4
and.w #%11110000,d5
or.w d4,d5
RETCMD
ENDM
rolbrn MACRO
move.w \1,d6
move.l d5,d4
roxr.l #1,d4
roxl.b #1,d6
bmi.s 2$
bcc.s 3$
or #2,ccr
bra.s 3$
2$ bcs.s 3$
or #2,ccr
3$ move.w ccr,d4
move.w d6,\1
and.w #%00001111,d4
and.w #%11110000,d5
or.w d4,d5
RETCMD
ENDM
FCMD_Rn rol_
FCMD_Rn rolb
_rol___ and.w #%111111,d4
lea ad_mw(pc),a6
move.l (a6,d4.l*4),a6
lea 1$(pc),a5
jmp (a6)
1$ move.l d5,d4
roxr.l #1,d4
roxl.w #1,d6
bmi.s 2$
bcc.s 3$
or #2,ccr
bra.s 3$
2$ bcs.s 3$
or #2,ccr
3$ move.w ccr,d4
and.w #%00001111,d4
and.w #%11110000,d5
or.w d4,d5
RET a6
_rolb__ and.w #%111111,d4
lea ad_mb(pc),a6
move.l (a6,d4.l*4),a6
lea 1$(pc),a5
jmp (a6)
1$ move.l d5,d4
roxr.l #1,d4
roxl.b #1,d6
bmi.s 2$
bcc.s 3$
or #2,ccr
bra.s 3$
2$ bcs.s 3$
or #2,ccr
3$ move.w ccr,d4
and.w #%00001111,d4
and.w #%11110000,d5
or.w d4,d5
RET a6
;-------------------------------------
; ROR(B) D - Cycle right shift
;
ror_rn MACRO
move.w \1,d6
move.l d5,d4
roxr.l #1,d4
roxr.w #1,d6
bmi.s 2$
bcc.s 3$
or #2,ccr
bra.s 3$
2$ bcs.s 3$
or #2,ccr
3$ move.w ccr,d4
move.w d6,\1
and.w #%00001111,d4
and.w #%11110000,d5
or.w d4,d5
RETCMD
ENDM
rorbrn MACRO
move.w \1,d6
move.l d5,d4
roxr.l #1,d4
roxr.b #1,d6
bmi.s 2$
bcc.s 3$
or #2,ccr
bra.s 3$
2$ bcs.s 3$
or #2,ccr
3$ move.w ccr,d4
move.w d6,\1
and.w #%00001111,d4
and.w #%11110000,d5
or.w d4,d5
RETCMD
ENDM
FCMD_Rn ror_
FCMD_Rn rorb
_ror___ and.w #%111111,d4
lea ad_mw(pc),a6
move.l (a6,d4.l*4),a6
lea 1$(pc),a5
jmp (a6)
1$ move.l d5,d4
roxr.l #1,d4
roxr.w #1,d6
bmi.s 2$
bcc.s 3$
or #2,ccr
bra.s 3$
2$ bcs.s 3$
or #2,ccr
3$ move.w ccr,d4
and.w #%00001111,d4
and.w #%11110000,d5
or.w d4,d5
RET a6
_rorb__ and.w #%111111,d4
lea ad_mb(pc),a6
move.l (a6,d4.l*4),a6
lea 1$(pc),a5
jmp (a6)
1$ move.l d5,d4
roxr.l #1,d4
roxr.b #1,d6
bmi.s 2$
bcc.s 3$
or #2,ccr
bra.s 3$
2$ bcs.s 3$
or #2,ccr
3$ move.w ccr,d4
and.w #%00001111,d4
and.w #%11110000,d5
or.w d4,d5
RET a6
;------------------------------------------
; ADC(B) D - Add carry bit
;
_adc___ and.w #%111111,d4
lea ad_mw(pc),a6
move.l (a6,d4.l*4),a6
lea 1$(pc),a5
jmp (a6)
1$ move.w d5,d4
and.w #1,d4
add.w d4,d6
move.w ccr,d4
and.w #%00001111,d4
and.w #%11110000,d5
or.w d4,d5
RET a6
_adcb__ and.w #%111111,d4
lea ad_mb(pc),a6
move.l (a6,d4.l*4),a6
lea 1$(pc),a5
jmp (a6)
1$ move.w d5,d4
and.w #1,d4
add.b d4,d6
move.w ccr,d4
and.w #%00001111,d4
and.w #%11110000,d5
or.w d4,d5
RET a6
;------------------------------------------
; SBC(B) D - Subtract carry bit
;
_sbc___ and.w #%111111,d4
lea ad_mw(pc),a6
move.l (a6,d4.l*4),a6
lea 1$(pc),a5
jmp (a6)
1$ move.w d5,d4
and.w #1,d4
sub.w d4,d6
move.w ccr,d4
and.w #%00001111,d4
and.w #%11110000,d5
or.w d4,d5
RET a6
_sbcb__ and.w #%111111,d4
lea ad_mb(pc),a6
move.l (a6,d4.l*4),a6
lea 1$(pc),a5
jmp (a6)
1$ move.w d5,d4
and.w #1,d4
sub.b d4,d6
move.w ccr,d4
and.w #%00001111,d4
and.w #%11110000,d5
or.w d4,d5
RET a6
;---------------------------------
; CMP(B) S,D - Compare
;
_cmp___ move.l d4,d6
and.w #%111111000000,d4
asr.l #6,d4
lea ad_rw(pc),a6
move.l (a6,d4.l*4),a6
CALL a6,a5
move.w d4,d7
and.w #%111111,d6
lea ad_rw(pc),a6
move.l (a6,d6.l*4),a6
CALL a6,a5
cmp.w d4,d7
move.w ccr,d4
and.w #%00001111,d4
and.w #%11110000,d5
or.w d4,d5
RETCMD
_cmpb__ move.l d4,d6
and.w #%111111000000,d4
asr.l #6,d4
lea ad_rb(pc),a6
move.l (a6,d4.l*4),a6
CALL a6,a5
move.w d4,d7
and.w #%111111,d6
lea ad_rb(pc),a6
move.l (a6,d6.l*4),a6
CALL a6,a5
cmp.b d4,d7
move.w ccr,d4
and.w #%00001111,d4
and.w #%11110000,d5
or.w d4,d5
RETCMD
;-------------------------------------
; BIT(B) S,D - Bit test
;
_bit___ move.l d4,d6
and.w #%111111000000,d4
asr.l #6,d4
lea ad_rw(pc),a6
move.l (a6,d4.l*4),a6
CALL a6,a5
move.w d4,d7
and.w #%111111,d6
lea ad_rw(pc),a6
move.l (a6,d6.l*4),a6
CALL a6,a5
and.w d7,d4
move.w ccr,d4
and.w #%00001100,d4
and.w #%11110001,d5
or.w d4,d5
RETCMD
_bitb__ move.l d4,d6
and.w #%111111000000,d4
asr.l #6,d4
lea ad_rb(pc),a6
move.l (a6,d4.l*4),a6
CALL a6,a5
move.w d4,d7
and.w #%111111,d6
lea ad_rb(pc),a6
move.l (a6,d6.l*4),a6
CALL a6,a5
and.b d7,d4
move.w ccr,d4
and.w #%00001100,d4
and.w #%11110001,d5
or.w d4,d5
RETCMD
;-------------------------------------
; BIS(B) S,D - Bit set
;
_bis___ move.l d4,d6
and.w #%111111000000,d4
asr.l #6,d4
lea ad_rw(pc),a6
move.l (a6,d4.l*4),a6
CALL a6,a5
and.w #%111111,d6
lea ad_mw(pc),a6
move.l (a6,d6.l*4),a6
lea 1$(pc),a5
jmp (a6)
1$ or.w d4,d6
move.w ccr,d4
and.w #%00001100,d4
and.w #%11110001,d5
or.w d4,d5
RET a6
_bisb__ move.l d4,d6
and.w #%111111000000,d4
asr.l #6,d4
lea ad_rb(pc),a6
move.l (a6,d4.l*4),a6
CALL a6,a5
and.w #%111111,d6
lea ad_mb(pc),a6
move.l (a6,d6.l*4),a6
lea 1$(pc),a5
jmp (a6)
1$ or.b d4,d6
move.w ccr,d4
and.w #%00001100,d4
and.w #%11110001,d5
or.w d4,d5
RET a6
;-------------------------------------
; BIC(B) S,D - Bit clearing
;
_bic___ move.l d4,d6
and.w #%111111000000,d4
asr.l #6,d4
lea ad_rw(pc),a6
move.l (a6,d4.l*4),a6
CALL a6,a5
and.w #%111111,d6
lea ad_mw(pc),a6
move.l (a6,d6.l*4),a6
lea 1$(pc),a5
jmp (a6)
1$ not.w d4
and.w d4,d6
move.w ccr,d4
and.w #%00001100,d4
and.w #%11110001,d5
or.w d4,d5
RET a6
_bicb__ move.l d4,d6
and.w #%111111000000,d4
asr.l #6,d4
lea ad_rb(pc),a6
move.l (a6,d4.l*4),a6
CALL a6,a5
and.w #%111111,d6
lea ad_mb(pc),a6
move.l (a6,d6.l*4),a6
lea 1$(pc),a5
jmp (a6)
1$ not.b d4
and.b d4,d6
move.w ccr,d4
and.w #%00001100,d4
and.w #%11110001,d5
or.w d4,d5
RET a6
;-------------------------------------
; ADD S,D - Add
;
_add___ move.l d4,d6
and.w #%111111000000,d4
asr.l #6,d4
lea ad_rw(pc),a6
move.l (a6,d4.l*4),a6
CALL a6,a5
and.w #%111111,d6
lea ad_mw(pc),a6
move.l (a6,d6.l*4),a6
lea 1$(pc),a5
jmp (a6)
1$ add.w d4,d6
move.w ccr,d4
and.w #%00001111,d4
and.w #%11110000,d5
or.w d4,d5
RET a6
;-------------------------------------
; SUB S,D - Subtract
;
_sub___ move.l d4,d6
and.w #%111111000000,d4
asr.l #6,d4
lea ad_rw(pc),a6
move.l (a6,d4.l*4),a6
CALL a6,a5
and.w #%111111,d6
lea ad_mw(pc),a6
move.l (a6,d6.l*4),a6
lea 1$(pc),a5
jmp (a6)
1$ sub.w d4,d6
move.w ccr,d4
and.w #%00001111,d4
and.w #%11110000,d5
or.w d4,d5
RET a6
;----------------------------------------
; XOR Rn,D - Exclusive OR
;
xor_rn MACRO
move.l d4,d6
move.w \1,d4
and.w #%111111,d6
lea ad_mw(pc),a6
move.l (a6,d6.l*4),a6
lea xor_rx(pc),a5
jmp (a6)
ENDM
xor_rx eor.w d4,d6
move.w ccr,d4
and.w #%00001100,d4
and.w #%11110001,d5
or.w d4,d5
RET a6
FCMD_Rn xor_
;--------------------------
; OPCODES DECODE ROUTINE
;--------------------------
; registers: R0-R7 as A0,A1,A2,A3,D0,D1,D2,D3
; D4 - working data
; A4 - emulation memory address
; D5 - processor status word (PSW)
decod moveq.l #-1,d0
CALLEXEC AllocSignal
moveq.l #1,d1
lsl.l d0,d1
move.l d1,decode_emt36_signal
moveq.l #-1,d0
CALLEXEC AllocSignal
moveq.l #1,d1
lsl.l d0,d1
move.l d1,decode_delay_signal
moveq.l #-1,d0
CALLEXEC AllocSignal
moveq.l #1,d1
lsl.l d0,d1
move.l d1,decode_sleep_signal
move.l sp,decode_init_stack
move.l #emul_buffer_mid,a4
clr.l d5 ;PS
move.l d5,a0 ;R0
move.l d5,a1 ;R1
move.l d5,a2 ;R2
move.l d5,a3 ;R3
clr.l d0 ;R4
clr.l d1 ;R5
move.l #512,d2 ;SP
reset move.l #$8000,d3 ;PC
clr.w int_flags
bsr reset_hw
dc_next
move.l intl_flags,d4
beq dc_rtt ;no flags
cmp.w #$8000,d4 ;only delay flag present?
bne 20$ ;no
clr.l d4
move.w d3,d4 ;get program counter
addq.w #2,d3 ;increase program counter
BK_RW d4,d4 ;get opcode
move.l #time_table,a6
move.w (a6,d4.l*2),d6 ;get precalculated opcode timing
sub.w d6,delay_counter
bpl.s 10$
move.w #3500,delay_counter ;reset timing counter
movem.l d0-a6,-(sp)
subq.w #1,slow_counter
bpl.s 5$
bclr.b #7,int_flags
bra.s 6$
5$ clr.l d0
clr.l d1
CALLEXEC SetSignal
and.l decode_delay_signal,d0
bne.s 7$
6$ move.w #50,slow_counter
7$ move.l decode_delay_signal,d0
CALLEXEC Wait ;wait for vblank
movem.l (sp)+,d0-a6
10$ move.l #decode_table,a6
move.l (a6,d4.l*4),a6 ;get opcode procedure address
jmp (a6)
20$ btst.l #10,d4 ; trace bit exception
beq.s 30$
move.w #@14,d6
bsr int
move.w int_flags,d4
30$ btst.l #8,d4 ; cpu restart
bne reset
btst.l #9,d4 ; STOP key exception
beq.s 40$
bclr.b #1,int_flags
move.w #4,d6
addq.w #2,d3 ;increase program counter
bra intc
40$ btst.l #0,d4 ; vector 100 - vblank exception
beq.s 50$
bclr.b #0,int_flags+1
bclr.b #0,intm_flags
move.w #@100,d6
bra intc
50$ btst.l #1,d4 ; vector 60 - first keyboard exception
beq.s 60$
bclr.b #1,int_flags+1
bclr.b #1,intm_flags
move.w #@60,d6
bra intc
60$ btst.l #2,d4 ; vector 274 - second keyboard exception
beq.s 70$
bclr.b #2,int_flags+1
bclr.b #2,intm_flags
move.w #@274,d6
bra intc
70$ btst.l #14,d4 ; terminate emulation process
beq.s 80$
addq.b #1,control_break_flag ;terminate main process
move.l control_proc_ptr,a1
move.l #ALL_BREAKF,d0
CALLEXEC Signal ;send Break to it
rts
80$ clr.l d4
dc_rtt move.w d3,d4
addq.w #2,d3
BK_RW d4,d4
move.l #decode_table,a6
move.l (a6,d4.l*4),a6
jmp (a6)
; int_flags bits:
; 0 - RESET
; 1 - STOP
; 2 - trace
; 6 - terminate process
; 7 - delay
; int_flags+1 & intm_flags bits:
; 0 - vector 100
; 1 - vector 60 (keyboard)
; 2 - vector 274 (--//--)
; registers: R0-R7 as A0,A1,A2,A3,D0,D1,D2,D3
; D4 - working data
; A4 - emulation memory address
; D5 - processor status word (PSW)
; label format: ad(addressing_mode_number)(register_number)(data_size)
;--------------------------------
; BYTE SOURCE ADDRESSING MODES
;--------------------------------
ad0xrb MACRO ; move byte from R
move.w \1,d4
RET a5
ENDM
ad1xrb MACRO ; move byte from (R)
BK_RB \1,d4
RET a5
ENDM
ad2xrb MACRO ; move byte from (R)+
BK_RB \1,d4
IFC '\1','p6'
addq.w #2,\1
ELSE
IFC '\1','p7'
addq.w #2,\1
ELSE
addq.w #1,\1
ENDC
ENDC
RET a5
ENDM
ad3xrb MACRO ; move byte from @(R)+
BK_RRW \1,d4
addq.w #2,\1
BK_RB d4,d4
RET a5
ENDM
ad4xrb MACRO ; move byte from -(R)
IFC '\1','p6'
subq.w #2,\1
ELSE
IFC '\1','p7'
subq.w #2,\1
ELSE
subq.w #1,\1
ENDC
ENDC
BK_RB \1,d4
RET a5
ENDM
ad5xrb MACRO ; move byte from @-(R)
subq.w #2,\1
BK_RRW \1,d4
BK_RB d4,d4
RET a5
ENDM
ad6xrb MACRO ; move byte from N(R)
BK_RRW d3,d4
addq.w #2,d3
add.w \1,d4
BK_RB d4,d4
RET a5
ENDM
ad7xrb MACRO ; move byte from @N(R)
BK_RRW d3,d4
addq.w #2,d3
add.w \1,d4
BK_RW d4,d4
BK_RB d4,d4
RET a5
ENDM
;--------------------------------
; WORD SOURCE ADDRESSING MODES
;--------------------------------
ad0xrw MACRO ; move word from R
move.w \1,d4
RET a5
ENDM
ad1xrw MACRO ; move word from (R)
BK_RRW \1,d4
RET a5
ENDM
ad2xrw MACRO ; move word from (R)+
BK_RRW \1,d4
addq.w #2,\1
RET a5
ENDM
ad3xrw MACRO ; move word from @(R)+
BK_RRW \1,d4
addq.w #2,\1
BK_RW d4,d4
RET a5
ENDM
ad4xrw MACRO ; move word from -(R)
subq.w #2,\1
BK_RRW \1,d4
RET a5
ENDM
ad5xrw MACRO ; move word from @-(R)
subq.w #2,\1
BK_RRW \1,d4
BK_RW d4,d4
RET a5
ENDM
ad6xrw MACRO ; move word from N(R)
BK_RRW d3,d4
addq.w #2,d3
add.w \1,d4
BK_RW d4,d4
RET a5
ENDM
ad7xrw MACRO ; move word from @N(R)
BK_RRW d3,d4
addq.w #2,d3
add.w \1,d4
BK_RW d4,d4
BK_RW d4,d4
RET a5
ENDM
;-------------------------------------
; BYTE DESTINATION ADDRESSING MODES
;-------------------------------------
ad0xwb MACRO ; move byte to R
move.w d4,\1
RETCMD
ENDM
ad1xwb MACRO ; move byte to (R)
BK_SB d4,\1
RETCMD
ENDM
ad2xwb MACRO ; move byte to (R)+
BK_SB d4,\1
IFC '\1','p6'
addq.w #2,\1
ELSE
IFC '\1','p7'
addq.w #2,\1
ELSE
addq.w #1,\1
ENDC
ENDC
RETCMD
ENDM
ad3xwb MACRO ; move byte to @(R)+
BK_RRW \1,d6
addq.w #2,\1
BK_SB d4,d6
RETCMD
ENDM
ad4xwb MACRO ; move byte to -(R)
IFC '\1','p6'
subq.w #2,\1
ELSE
IFC '\1','p7'
subq.w #2,\1
ELSE
subq.w #1,\1
ENDC
ENDC
BK_SB d4,\1
RETCMD
ENDM
ad5xwb MACRO ; move byte to @-(R)
subq.w #2,\1
BK_RRW \1,d6
BK_SB d4,d6
RETCMD
ENDM
ad6xwb MACRO ; move byte to N(R)
BK_RRW d3,d6
addq.w #2,d3
add.w \1,d6
BK_SB d4,d6
RETCMD
ENDM
ad7xwb MACRO ; move byte to @N(R)
BK_RRW d3,d6
addq.w #2,d3
add.w \1,d6
BK_RW d6,d6
BK_SB d4,d6
RETCMD
ENDM
;-------------------------------------
; WORD DESTINATION ADDRESSING MODES
;-------------------------------------
ad0xww MACRO ; move word to R
move.w d4,\1
RETCMD
ENDM
ad1xww MACRO ; move word to (R)
move.w \1,d6
BK_SW d4,d6
RETCMD
ENDM
ad2xww MACRO ; move word to (R)+
move.w \1,d6
BK_SW d4,d6
addq.w #2,\1
RETCMD
ENDM
ad3xww MACRO ; move word to @(R)+
BK_RRW \1,d6
addq.w #2,\1
BK_SW d4,d6
RETCMD
ENDM
ad4xww MACRO ; move word to -(R)
subq.w #2,\1
move.w \1,d6
BK_SW d4,d6
RETCMD
ENDM
ad5xww MACRO ; move word to @-(R)
subq.w #2,\1
BK_RRW \1,d6
BK_SW d4,d6
RETCMD
ENDM
ad6xww MACRO ; move word to N(R)
BK_RRW d3,d6
addq.w #2,d3
add.w \1,d6
BK_SW d4,d6
RETCMD
ENDM
ad7xww MACRO ; move word to @N(R)
BK_RRW d3,d6
addq.w #2,d3
add.w \1,d6
BK_RW d6,d6
BK_SW d4,d6
RETCMD
ENDM
;-----------------------------------------
; WORD SOURCE ADDRESSING MODES FOR JUMP
;-----------------------------------------
ad0xjw MACRO ; move word from R
move.w d3,d6 ; = NOP
RET a5
ENDM
ad1xjw MACRO ; move word from (R)
move.w \1,d6
RET a5
ENDM
ad2xjw MACRO ; move word from (R)+
move.w \1,d6
addq.w #2,\1
RET a5
ENDM
ad3xjw MACRO ; move word from @(R)+
BK_RRW \1,d6
addq.w #2,\1
RET a5
ENDM
ad4xjw MACRO ; move word from -(R)
subq.w #2,\1
move.w \1,d6
RET a5
ENDM
ad5xjw MACRO ; move word from @-(R)
subq.w #2,\1
BK_RRW \1,d6
RET a5
ENDM
ad6xjw MACRO ; move word from N(R)
BK_RRW d3,d6
addq.w #2,d3
add.w \1,d6
RET a5
ENDM
ad7xjw MACRO ; move word from @N(R)
BK_RRW d3,d4
addq.w #2,d3
add.w \1,d4
BK_RW d4,d6
RET a5
ENDM
;--------------------------------------
; BYTE MODIFICATION ADDRESSING MODES
;--------------------------------------
ad0xmb MACRO ; byte modification in R
move.w \1,d6
CALL a5,a6
move.w d6,\1
RETCMD
ENDM
ad1xmb MACRO ; byte modification in (R)
BK_RB \1,d6
CALL a5,a6
BK_SB d6,\1
RETCMD
ENDM
ad2xmb MACRO ; byte modification in (R)+
BK_RB \1,d6
CALL a5,a6
BK_SB d6,\1
IFC '\1','p6'
addq.w #2,\1
ELSE
IFC '\1','p7'
addq.w #2,\1
ELSE
addq.w #1,\1
ENDC
ENDC
RETCMD
ENDM
ad3xmb MACRO ; byte modification in @(R)+
BK_RRW \1,d7
addq.w #2,\1
BK_RB d7,d6
CALL a5,a6
BK_SB d6,d7
RETCMD
ENDM
ad4xmb MACRO ; byte modification in -(R)
IFC '\1','p6'
subq.w #2,\1
ELSE
IFC '\1','p7'
subq.w #2,\1
ELSE
subq.w #1,\1
ENDC
ENDC
BK_RB \1,d6
CALL a5,a6
BK_SB d6,\1
RETCMD
ENDM
ad5xmb MACRO ; byte modification in @-(R)
subq.w #2,\1
BK_RRW \1,d7
BK_RB d7,d6
CALL a5,a6
BK_SB d6,d7
RETCMD
ENDM
ad6xmb MACRO ; byte modification in N(R)
BK_RRW d3,d7
addq.w #2,d3
add.w \1,d7
BK_RB d7,d6
CALL a5,a6
BK_SB d6,d7
RETCMD
ENDM
ad7xmb MACRO ; byte modification in @N(R)
BK_RRW d3,d7
addq.w #2,d3
add.w \1,d7
BK_RW d7,d7
BK_RB d7,d6
CALL a5,a6
BK_SB d6,d7
RETCMD
ENDM
;--------------------------------------
; WORD MODIFICATION ADDRESSING MODES
;--------------------------------------
ad0xmw MACRO ; word modification in R
move.w \1,d6
CALL a5,a6
move.w d6,\1
RETCMD
ENDM
ad1xmw MACRO ; word modification in (R)
move.w \1,d7
BK_RW d7,d6
CALL a5,a6
BK_NSW d6,d7
RETCMD
ENDM
ad2xmw MACRO ; word modification in (R)+
move.w \1,d7
addq.w #2,\1
BK_RW d7,d6
CALL a5,a6
BK_NSW d6,d7
RETCMD
ENDM
ad3xmw MACRO ; word modification in @(R)+
BK_RRW \1,d7
addq.w #2,\1
BK_RW d7,d6
CALL a5,a6
BK_NSW d6,d7
RETCMD
ENDM
ad4xmw MACRO ; word modification in -(R)
subq.w #2,\1
move.w \1,d7
BK_RW d7,d6
CALL a5,a6
BK_NSW d6,d7
RETCMD
ENDM
ad5xmw MACRO ; word modification in @-(R)
subq.w #2,\1
BK_RRW \1,d7
BK_RW d7,d6
CALL a5,a6
BK_NSW d6,d7
RETCMD
ENDM
ad6xmw MACRO ; word modification in N(R)
BK_RRW d3,d7
addq.w #2,d3
add.w \1,d7
BK_RW d7,d6
CALL a5,a6
BK_NSW d6,d7
RETCMD
ENDM
ad7xmw MACRO ; word modification in @N(R)
BK_RRW d3,d7
addq.w #2,d3
add.w \1,d7
BK_RW d7,d7
BK_RW d7,d6
CALL a5,a6
BK_NSW d6,d7
RETCMD
ENDM
;-----------------------------
; ADDRESSING MODES ROUTINES
;-----------------------------
;
ad_reg MACRO
ad\2\1\3
ad\2x\3 p\1
ENDM
ad_nreg MACRO
ad_reg 0,\1,\2
ad_reg 1,\1,\2
ad_reg 2,\1,\2
ad_reg 3,\1,\2
ad_reg 4,\1,\2
ad_reg 5,\1,\2
ad_reg 6,\1,\2
ad_reg 7,\1,\2
ENDM
ad_nad MACRO
ad_nreg 0,\1
ad_nreg 1,\1
ad_nreg 2,\1
ad_nreg 3,\1
ad_nreg 4,\1
ad_nreg 5,\1
ad_nreg 6,\1
ad_nreg 7,\1
ENDM
ad_nad rb
ad_nad rw
ad_nad wb
ad_nad ww
ad_nad mb
ad_nad mw
ad_nad jw
section tables,data
cnop 0,4
;-------------------------------------
; HARDWARE REGISTERS TABLE FOR READ
;-------------------------------------
;
dc.l 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
dc.l rp177660
dc.l rp177662
dc.l rp177664
dc.l 0,0,0,0,0
dc.l rp177700
dc.l rp177702
dc.l rp177704
dc.l rp177706
dc.l rp177710
dc.l rp177712
dc.l rp177714
dc.l rp177716
dc.l 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
prt_vm1
;--------------------------------------
; HARDWARE REGISTERS TABLE FOR WRITE
;--------------------------------------
;
dc.l 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
dc.l wp177660
dc.l 0
dc.l wp177664
dc.l 0,0,0,0,0
dc.l wp177700
dc.l wp177702
dc.l wp177704
dc.l wp177706
dc.l wp177710
dc.l wp177712
dc.l wp177714
dc.l wp177716
dc.l 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
pwt_vm1
;-----------------------------------
; PROCESSOR OPCODES ADDRESS TABLE
;-----------------------------------
;
ct_vm1
dCMD _halt__,1 ;000000
dCMD _wait__,1 ;000001
dCMD _rti___,1 ;000002
dCMD _bpt___,1 ;000003
dCMD _iot___,1 ;000004
dCMD _reset_,1 ;000005
dCMD _rtt___,1 ;000006
dCMD _rsrv__,57
dCMD _jmp___,64 ;0001xx
CMD_Rm _rts_ ;000200
dCMD _rsrv__,24
dCMD _cl____,16 ;000240
dCMD _se____,16 ;000260
dCMD _swab__,64 ;0003xx
dCMD _br____,256 ;000400
dCMD _bne___,256 ;001000
dCMD _beq___,256 ;001400
dCMD _bge___,256 ;002000
dCMD _blt___,256 ;002400
dCMD _bgt___,256 ;003000
dCMD _ble___,256 ;003400
CMD_Rn _jsr_ ;004xxx
CMD_Rx _clr_ ;0050xx
dCMD _com___,64 ;0051xx
dCMD _inc___,64 ;0052xx
dCMD _dec___,64 ;0053xx
dCMD _neg___,64 ;0054xx
dCMD _adc___,64 ;0055xx
dCMD _sbc___,64 ;0056xx
CMD_Rx _tst_ ;0057xx
CMD_Rx _ror_ ;0060xx
CMD_Rx _rol_ ;0061xx
CMD_Rx _asr_ ;0062xx
CMD_Rx _asl_ ;0063xx
dCMD _mark__,64 ;0064xx
dCMD _rsrv__,128 ;006500
dCMD _sxt___,64 ;0067xx
dCMD _rsrv__,512 ;007000
; MOV
tm__rx MACRO
CMD_Rm _m_t_
dCMD _m_f_\1,56
ENDM
tm__rx r0
tm__rx r1
tm__rx r2
tm__rx r3
tm__rx r4
tm__rx r5
tm__rx r6
tm__rx r7
REPT 56
CMD_Rm _m_t_
dCMD _mov___,56
ENDR
;
dCMD _cmp___,4096 ;02xxxx
dCMD _bit___,4096 ;03xxxx
dCMD _bic___,4096 ;04xxxx
dCMD _bis___,4096 ;05xxxx
dCMD _add___,4096 ;06xxxx
dCMD _rsrv__,2048 ;070000
CMD_Rn _xor_ ;074xxx
dCMD _rsrv__,1024 ;075xxx
CMD_Rn _sob_ ;077xxx
dCMD _bpl___,256 ;100000
dCMD _bmi___,256 ;100400
dCMD _bhi___,256 ;101000
dCMD _blos__,256 ;101400
dCMD _bvc___,256 ;102000
dCMD _bvs___,256 ;102400
dCMD _bcc___,256 ;103000
dCMD _bcs___,256 ;103400
dCMD _emt___,30 ;104000
dCMD _emt_36,1 ;104036
dCMD _emt___,225 ;104000
dCMD _trap__,256 ;104400
CMD_Rx _clrb ;1050xx
dCMD _comb__,64 ;1051xx
dCMD _incb__,64 ;1052xx
dCMD _decb__,64 ;1053xx
dCMD _negb__,64 ;1054xx
dCMD _adcb__,64 ;1055xx
dCMD _sbcb__,64 ;1056xx
CMD_Rx _tstb ;1057xx
CMD_Rx _rorb ;1060xx
CMD_Rx _rolb ;1061xx
CMD_Rx _asrb ;1062xx
CMD_Rx _aslb ;1063xx
dCMD _mtps__,64 ;1064xx
dCMD _rsrv__,128 ;1065xx
dCMD _mfps__,64 ;1067xx
dCMD _rsrv__,512 ;107xxx
; MOVB
tmb_rx MACRO
CMD_Rm _mbt_
dCMD _mbf_\1,56
ENDM
tmb_rx r0
tmb_rx r1
tmb_rx r2
tmb_rx r3
tmb_rx r4
tmb_rx r5
tmb_rx r6
tmb_rx r7
REPT 56
CMD_Rm _mbt_
dCMD _movb__,56
ENDR
dCMD _cmpb__,4096 ;12xxxx
dCMD _bitb__,4096 ;13xxxx
dCMD _bicb__,4096 ;14xxxx
dCMD _bisb__,4096 ;15xxxx
dCMD _sub___,4096 ;16xxxx
dCMD _rsrv__,4096 ;17xxxx
dc.l 0
cnop 0,4
monotag dc.l SA_DisplayID,$8000
mono_x dc.l SA_Left,64
mono_y dc.l SA_Top,0
dc.l SA_Quiet,1
dc.l SA_AutoScroll,1
dc.l SA_Width,512
dc.l SA_Height,256
dc.l SA_Depth,1
dc.l SA_Title,w_s_title
dc.l SA_Colors,mono_colorspec
dc.l TAG_END,0
colortag dc.l SA_DisplayID,0
color_x dc.l SA_Left,32
color_y dc.l SA_Top,0
dc.l SA_Quiet,1
dc.l SA_AutoScroll,1
dc.l SA_Width,256
dc.l SA_Height,256
dc.l SA_Depth,2
dc.l SA_Title,w_s_title
dc.l SA_Colors,color_colorspec
dc.l TAG_END,0
decode_proc_tags
dc.l NP_Entry,decod
dc.l NP_Priority,-1
dc.l NP_Name,decode_proc_name
dc.l TAG_END,0
refresh_proc_tags
dc.l NP_Entry,refresh_proc
dc.l NP_Priority,1
dc.l NP_Name,refresh_proc_name
dc.l TAG_END,0
mono_colorspec dc.w 0,0,0,0
dc.w 1,12,12,12
dc.w 17,0,0,0
dc.w 18,0,0,0
dc.w 19,0,0,0
dc.w -1
color_colorspec dc.w 0,0,0,0
dc.w 1,0,0,15
dc.w 2,0,15,0
dc.w 3,15,0,0
dc.w 17,0,0,0
dc.w 18,0,0,0
dc.w 19,0,0,0
dc.w -1
monotab dc.w $0000,$0DDD
colortab dc.w $0000,$000F,$00F0,$0F00
w_bk_screen
dc.w 0,0 ;x&y coordinates
wwidth dc.w 256,256 ;width and height
dc.b 0,0 ;default pens
dc.l VANILLAKEY!RAWKEY ;IDCMP flags
dc.l ACTIVATE!SIMPLE_REFRESH!BORDERLESS!BACKDROP!RMBTRAP
dc.l 0 ;no gadgets
dc.l 0 ;no checkmarks
dc.l w_s_title
sbs_ptr dc.l 0 ;emulator screen
dc.l 0 ;no bitmap
dc.w 0,0,0,0 ;minimum, irrelevant as no sizing gadget
dc.w CUSTOMSCREEN
c_bk_screen
dc.w 0,0
dc.w 1,1
dc.b 0,0
dc.l CLOSEWINDOW!VANILLAKEY!RAWKEY
dc.l WINDOWCLOSE!ACTIVATE!SIMPLE_REFRESH!BORDERLESS!RMBTRAP
dc.l 0
dc.l 0
dc.l w_s_title
sbs_cop dc.l 0
dc.l 0
dc.w 0,0,0,0
dc.w CUSTOMSCREEN
keytab1 dc.b $50,128+01
dc.b $51,000+03
dc.b $52,128+11
dc.b $53,000+22
dc.b $54,000+23
dc.b $55,128+02
dc.b $56,128+04
dc.b $57,128+00
dc.b $58,000+12
dc.b $64,000+14 ;RUS
dc.b $65,000+15 ;LAT
dc.b $4C,000+26 ;up
dc.b $4D,000+27 ;down
dc.b $4F,000+08 ;left
dc.b $4E,000+25 ;right
dc.b 0
keytab2 dc.b 009,128+09
dc.b 008,000+24
dc.b 127,000+19
dc.b 013,000+10
dc.b 0
dc.b $87,$B6,$D4,$AF,$83,$AA,$BF,$94
dc.b $82,$D4,$AD,$BE,$81,$76,$B5,$95
dc.b $A5,$3C,$9A,$5E,$D4,$A1,$9E,$A2
dc.b $2A,$B4,$9F,$87,$80,$8D,$3E,$9C
dc.b $FE,$E0,$E1,$F6,$E4,$E5,$F4,$E3
dc.b $F5,$E8,$E9,$EA,$EB,$EC,$ED,$EE
dc.b $EF,$FF,$F0,$F1,$F2,$F3,$E6,$E2
dc.b $FC,$FB,$E7,$F8,$FD,$F9,$F7,$FA
dc.b $DE,$C0,$C1,$D6,$C4,$C5,$D4,$C3
dc.b $D5,$C8,$C9,$CA,$CB,$CC,$CD,$CE
dc.b $CF,$DF,$D0,$D1,$D2,$D3,$C6,$C2
dc.b $DC,$DB,$C7,$D8,$DD,$D9,$D7,$DA
koi8_to_1251_table
cnop 0,4
_SysBase dc.l 0
_IntuitionBase dc.l 0 ;intuition
_GfxBase dc.l 0 ;graphics
_DOSBase dc.l 0 ;dos
WB_return_message dc.l 0
emt36_block_ptr dc.l 0
wbs_ptr dc.l 0
cbs_ptr dc.l 0
old_wbs_ptr dc.l 0
old_cbs_ptr dc.l 0
old_sbs_ptr dc.l 0
return_code dc.l 0
ROM_file_handle dc.l 0
emt36_handle dc.l 0
emt36_ptr dc.l 0
decode_init_stack dc.l 0
decode_emt36_signal dc.l 0
decode_delay_signal dc.l 0
decode_sleep_signal dc.l 0
decode_proc_ptr dc.l 0
refresh_proc_ptr dc.l 0
control_proc_ptr dc.l 0
control_proc_signal dc.l 0
intl_flags dc.w 0
int_flags dc.w 0
delay_counter dc.w 2000
slow_counter dc.w 50
emt36_adr dc.w 0
emt36_len dc.w 0
p177660 dc.w 0
p177662 dc.w 0
p177664 dc.w @1330
c177664 dc.w @1330
p177714 dc.w 0
p177716 dc.w @100340
intm_flags dc.b 0
refresh_counter dc.b 0
control_proc_signal_bit dc.b 0
bk_color_mode_flag dc.b -1
bk_color_mode dc.b -1
control_break_flag dc.b 0
refresh_break_flag dc.b 0
rus_flag dc.b 0
ROM_load_enable dc.b 0
version dc.b '$VER: '
w_s_title dc.b 'bkemul 1.6 beta',0
ROM_file_name dc.b 'PROGDIR:bk_rom',0
decode_proc_name dc.b '1801BM1 emulation',0
refresh_proc_name dc.b 'Screen refresh',0
name_full dc.b 'PROGDIR:bkfiles/'
name_buffer ds.b 18
ds.b 6
comment_buffer dc.b 0
intname INTNAME
grafname GRAFNAME
dosname DOSNAME
even
; section databuf,bss
;data_buffer
; ds.l $10000
section decode,bss
decode_table
ds.l $10000
section time,bss
time_table
ds.w $10000
section conv,bss
conv_table
ds.l $10000
section delta,bss
delta_buffer
ds.b $4000
section embuf,bss
emul_buffer_begin
ds.b $8000
emul_buffer_mid
ds.b $8000
emul_buffer_end
section fibbuf,bss
fib_buffer
ds.b fib_SIZEOF
end